package com.franklin.ideaplugin.easytesting.linemarker;

import cn.hutool.core.collection.CollectionUtil;
import com.franklin.ideaplugin.api.linemarker.AbstractLineMarkerProvider;
import com.franklin.ideaplugin.api.utils.PsiUtil;
import com.franklin.ideaplugin.easytesting.icon.PluginIcons;
import com.franklin.ideaplugin.easytesting.rpc.RegistryCenter;
import com.franklin.ideaplugin.easytesting.rpc.entity.RegistryData;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiMethodImpl;
import com.intellij.psi.util.PsiMethodUtil;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author Ye Junhui
 * @since 2023/5/12
 */
public class EasyTestingMethodLineMarker extends AbstractLineMarkerProvider<PsiMethod> {
    @Override
    protected boolean isMarkerTarget(@NotNull PsiElement psiElement) {
        if (!(psiElement.getContainingFile() instanceof PsiJavaFile)){
            return false;
        }
        if (!(psiElement instanceof PsiIdentifier)){
            return false;
        }
        PsiElement parent = psiElement.getParent();
        if (!(parent instanceof PsiMethod)){
            return false;
        }
        PsiMethod interfaceClassName = (PsiMethod) parent;
        PsiClass psiClass = interfaceClassName.getContainingClass();
        if (Objects.isNull(psiClass)){
            return false;
        }
        if (psiClass.isAnnotationType()){
            return false;
        }
        if (interfaceClassName.isConstructor()){
            return false;
        }
        if (PsiMethodUtil.isMainMethod(interfaceClassName)){
            return false;
        }
        List<RegistryData> registryDataList = RegistryCenter.getRegisterServer(interfaceClassName.getContainingFile());
        return CollectionUtil.isNotEmpty(registryDataList);
    }

    @Override
    public @NotNull Icon getIcon() {
        return PluginIcons.RUN_ICON;
    }

    @Override
    protected PsiMethod getObject(PsiElement psiElement) {
        if (!isMarkerTarget(psiElement)){
            return null;
        }
        psiElement = psiElement.getParent();
        return ((PsiMethodImpl) psiElement);
    }

    @Override
    public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement psiElement) {
        if (!isMarkerTarget(psiElement)){
            return null;
        }
        PsiMethod interfaceClassName = getObject(psiElement);
        return new SelectMethodLineMarkerInfo(
                interfaceClassName,
                getIcon(),
                (Navigatable) interfaceClassName.getNavigationElement(),
                Collections.singleton("")
        );
    }
}
